import os
from copy import deepcopy
import shutil
try:
    from .cvio import cvio
    from .running_faster import Runner
except:
    from cvio import cvio
    from running_faster import Runner
import numpy as np

import pandas as pd
from urllib import request
import requests

from collections import Counter


_labelme_format = {
    "imagePath": "",
    "imageHeight": 0,
    "imageWidth": 0,
    "imageData": None,
    "lineColor": [
        0,
        255,
        0,
        128
    ],
    "fillColor": [
        255,
        0,
        0,
        128
    ],
    "flags": {},
    "shapes": [
        # {
        #     "line_color":None,
        #     "fill_color":None,
        #     "label":"",
        #     "shape_type":"polygon",
        #     "flags":{},
        #     "points":[],
        # }
    ]
}

def boxInfoListToLabelMe(src, keepLayer=True, keepDaiding=True):
    resList = cvio.load_img_ann_list(src)

    _shape_ = {"line_color": None,
               "fill_color": None,
               "label": "",
               "shape_type": "polygon",
               "flags": {},
               "points": []}

    for i, (img,ann) in enumerate(resList,1):
        print(i, os.path.basename(img))
        ann_info = cvio.load_ann(ann)
        imageInfo = ann_info['imageInfo']
        if not len(imageInfo):
            continue
        height = imageInfo['height']
        width = imageInfo['width']
        boxInfo = ann_info['boxInfo']
        labelme_info = deepcopy(_labelme_format)
        labelme_info['imagePath'] = os.path.basename(img)
        labelme_info['imageData'] = None
        labelme_info['imageWidth'] = width
        labelme_info['imageHeight'] = height
        labelme_info['distance'] = imageInfo['distance']
        labelme_info['isVision'] = imageInfo['isVision']
        if 'layerLine' in ann_info:
            labelme_info['layerLine'] = ann_info['layerLine']
        if 'layerOut' in ann_info:
            labelme_info['layerOut'] = ann_info['layerOut']
        shapes = []
        labels = []
        for skuInfo in boxInfo:
            shape = deepcopy(_shape_)
            label = skuInfo['skuName']
            if 'daiding_101' in label and not keepDaiding:
                continue
            shape['label'] = label
            location = skuInfo['location']
            xmin = location['xmin'] * width
            ymin = location['ymin'] * height
            xmax = location['xmax'] * width
            ymax = location['ymax'] * height
            ply = [[xmin, ymin], [xmin, ymax], [xmax, ymax], [xmax, ymin]]
            if 'score' in skuInfo:
                shape['score'] = skuInfo['score']
            if 'layer' in skuInfo:
                shape['label'] = '%s层_%s' % (skuInfo['layer'], label) if keepLayer else label
                shape['layer'] = skuInfo['layer']
            shape['points'] = ply
            shapes.append(shape)
            labels.append(shape['label'])

        shapes = [shapes[i] for i in np.argsort(np.array(labels))]
        labelme_info['shapes'] = shapes

        cvio.write_ann(labelme_info, ann)
        # cvio.write_ann(labelme_info, os.path.join(
        #    dst, os.path.basename(ann)))
        # shutil.copy(img, os.path.join(dst, os.path.basename(img)))


def labelme2bboxInfo(src):
    filelist = cvio.load_img_ann_list(src)
    for i, (img,ann) in enumerate(filelist,1):
        print(i, os.path.basename(img))
        ann_info = cvio.load_ann(ann)
        height = ann_info['imageHeight']
        width = ann_info['imageWidth']
        distance = ann_info['distance'] if 'distance' in ann_info else 0
        isVision = ann_info['isVision'] if 'isVision' in ann_info else 0
        imageInfo = {'width': width, 'height': height,
                     'distance': distance, 'isVision': isVision}
        bboxInfo = []
        layerNum = 0
        labels = []
        for shape in ann_info['shapes']:
            # layer, skuName = shape['label'].split('层_')
            skuName = shape['label'].split('层_')[-1]
            labels.append(skuName)
            points = np.array(shape['points'])
            xmin = points[:, 0].min() / width
            ymin = points[:, 1].min() / height
            xmax = points[:, 0].max() / width
            ymax = points[:, 1].max() / height
            location = dict(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax)
            boxInfo = dict(skuName=skuName, location=location)
            if 'score' in shape:
                boxInfo['score'] = shape['score']
            if 'layer' in shape:
                layer = shape['layer']
                boxInfo['layer'] = layer
                layerNum = max(int(layer), layerNum)
            bboxInfo.append(boxInfo)
            
        skuStat = []
        for name, count in dict(Counter(labels)).items():
            skuStat.append(dict(skuName=name, count=count))

        layerOut = ann_info['layerOut'] if 'layerOut' in ann_info else []
        layerLine = ann_info['layerLine'] if 'layerLine' in ann_info else []
        result = {'layerOut': layerOut, 'layerLine': layerLine}
        result['boxInfo'] = bboxInfo
        result['imageInfo'] = imageInfo
        result['skuStat'] = skuStat
        result['layerNum'] = layerNum

        cvio.write_ann(result, ann)
        # cvio.write_ann(result, os.path.join(dst, os.path.basename(ann)))
        # shutil.copy(img, os.path.join(dst, os.path.basename(img)))


def downloadDetectResults(src, dst):
    xlsxIfno = pd.read_excel(src)

    xlsxInfo = dict(xlsxIfno)

    urlRes = xlsxInfo['结果图链接']
    urlTxt = xlsxInfo['拼接原始结果']

    if not os.path.exists(dst):
        #shutil.rmtree(dst)
        os.makedirs(dst)

    num = len(urlRes)

    for i in range(num):
        res = urlRes[i]
        txt = urlTxt[i]
        name = os.path.basename(res)
        respath = os.path.join(dst, name)
        if os.path.exists(respath):
            continue
        annpath = os.path.join(
            dst, '%s.json' % os.path.splitext(name)[0])
        try:
            request.urlretrieve(res, respath)
            request.urlretrieve(txt, annpath)
        except:
            print("HTTPERROR", res)


def load_aixtion_result(src):
    res = pd.read_excel(src)
    result = {}
    for k, v in res.items():
        v = list(v)
        k, v = v[0], v[1:]
        result[k] = v
    return result


def down_load_aixtion_data(src, dst, imgOrg='原图链接', imgRes='结果图链接', detRes='结果数据'):
    result = load_aixtion_result(src)
    imgOrgList = result['原图链接']
    imgResList = result['结果图链接']
    detResList = result['结果数据']
    n = len(imgOrgList)
    for i, (org, res, det) in enumerate(zip(imgOrgList, imgResList, detResList), 1):
        name = os.path.basename(org)
        orgpath = os.path.join(dst, imgOrg, name)
        respath = os.path.join(dst, imgRes, name)
        annpath = os.path.join(dst, detRes, '%s.json' %
                               os.path.splitext(name)[0])
        try:
            if imgOrg:
                if not os.path.exists(os.path.dirname(orgpath)):
                    #shutil.rmtree(os.path.dirname(orgpath))
                    os.makedirs(os.path.dirname(orgpath))
                request.urlretrieve(org, orgpath)
            if imgRes:
                if not os.path.exists(os.path.dirname(respath)):
                    #shutil.rmtree(os.path.dirname(respath))
                    os.makedirs(os.path.dirname(respath))
                request.urlretrieve(res, respath)
            if detRes:
                if not os.path.exists(os.path.dirname(annpath)):
                    #shutil.rmtree(os.path.dirname(annpath))
                    os.makedirs(os.path.dirname(annpath))
                request.urlretrieve(det, annpath)
                print('[%d/%d] %s' % (i, n, name))
        except:
            print("HTTPERROR", i, name)

def get_url_pic(url, dst):
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintoosh; Intel Mac OS X 10_14_68) AppleWebKit/538.36 (KHTML, like Gecko) Chrome/76.0.3904.97 Safari/537.36'
    }
    req = requests.get(url=url, headers=headers)
    open(dst,'wb').write(req.content)

def download_oss_images(xls_src, img_dst,
                        sheet='', rename=False, imgflag=True,
                        prefix='', table='original_image', spec_ext=None,
                        worker='process', num_workers=4):
    ext = os.path.splitext(xls_src)[1]
    if ext in ('.xlsx', '.xls'):
        read = pd.read_excel
    elif ext in ['.csv']:
        read = pd.read_csv
    else:
        raise 'Expected input file with postfix in (".xls", ".xls", ".csv"), but got "%s".' % ext
    if sheet not in (None, ''):
        urls = read(xls_src, sheet_name=sheet)[table]
    else:
        urls = read(xls_src)[table]

    n = len(urls)
    if n <= 0:
        return
    if not os.path.exists(img_dst):
        os.makedirs(img_dst)
    runner = Runner()
    for i, url in enumerate(urls, 1):
        try:
            bn = os.path.basename(url)
            bn = bn.replace('\\', '-').replace('/', '-').replace('*', '-').replace('?', '-').replace('|', '-').replace(':', '-').replace('<', '-').replace('>', '-')
            ext = os.path.splitext(bn)[1]
            if imgflag and ext.lower() not in ('.jpg', '.jpeg', '.tif', '.tiff', '.png'):
                ext = '.jpg'
            if spec_ext and not imgflag:
                if not spec_ext.startswith('.'):
                    spec_ext = '.%s' % spec_ext
                ext = spec_ext
                bn = os.path.splitext(bn)[0] + ext
            if rename:
                bn = '%06d%s' % (i, ext) if prefix in (None, '') else '%s_%03d%s' % (prefix, i, ext)
            dst = os.path.join(img_dst, bn)
            # request.urlretrieve(url, dst)
            print('[%d/%d] %s' % (i, n, url))
            runner.append(down_pic, (i, n, url, dst))
        except Exception as e:
            print(e)

    runner.run(mode=worker, num_workers=num_workers)

def down_pic(i, n, url, dst):
    print('[%d/%d]' % (i, n), os.path.basename(dst))
    try:
        if os.path.exists(dst):
            return
        request.urlretrieve(url, dst)
    except Exception as e:
        print(e)

if __name__ == '__main__':
    xls_src = r'E:\Documents\WXWork\1688850179089749\Cache\File\2022-08\ty.xlsx'
    img_dst = r'G:\data\datasets\drink\hongniu\ai\images\ty'
    download_oss_images(xls_src, img_dst,
                            sheet='', rename=False, imgflag=True,
                            prefix='', table='url', spec_ext=None,
                            worker='thread', num_workers=8)    